软件开发指导


1. 芯片及外设介绍

差异:

335R(3M@30,64M ddr,QFN88封装)

337DE(5M@25,128M ddr,QFN128封装)


2. 芯片启动流程和norflash分区

IPL IPL_CUST 和UBOOT KERNEL查找分区表的方法如下:

修改分区表的方法如下:

详细说明请参考《系统分区》。

注意:

  1. 如果ENV分区位置调整,需要对应更改uboot代码include/configs/infinity6b0.h,把宏CONFIG_ENV_OFFSET做对应修改。

  2. Kernel可以不读取分区表,使用bootargs传mtdparts的方式:

    打开CONFIG_MTD_CMDLINE_PARTS,去掉CONFIG_MS_FLASH_ISP_MXP_PARTS。bootars里的 mtdparts 的名字必须是NOR_FLASH 比如 :bootargs=mtdparts=NOR_FLASH:320K(boot),2048K(kernel),12544K(rootfs),64K(miservice),1M(config),-(customer) root=/dev/mtdblock2 rootfstype=squashfs


3. 多媒体驱动框架

  1. 文件系统里必须存在的工具、so 、ko和配置文件请参考模块驱动和链接库使用说明.

  2. Busybox下载:https://busybox.net/downloads/  (公板使用版本:1.20.2),公板使用的config联系FAE提供。


4. Iqfile和apibin file的区别

  1. Iqfile是图像的基础效果,所有sensor共用;图像质量比较差,只是用于保证应用出图。Iqfile是应用运行过程,驱动自动去加载的。

  2. Apibin file是图像的基础效果,一般是针对sensor调出最佳的图像效果;需要应用主动调用MI_ISP_API_CmdLoadBinFile()加载。(公板目前只提供了imx307的api bin file)


5. 多媒体模块介绍与模块串联出流

常见场景

  • 一路jpeg。

  • 一路主码流。

  • 一路子码流。

  • 一路MD算法。


6. 模块介绍

6.1. 模块之间的串联

VPE 4个port的区别:

  • Port 0:既支持frame mode,也支持不占用内存的Realtime mode(IMI mode)。

  • Port 1:既支持frame mode,也支持比较省内存的ring mode。

  • Port 2:只支持frame mode。

  • Port 3:虚拟Port,后面必须通过Realtime mode绑定DIVP。

  • 除了Port 3,其他Port之后都可以同时bind多个其他模块,DIVP/VENC/VDF 或者 出YUV数据。

6.2. 绑定模式

  1. frame mode

    • 占用多张yuv内存。(由depth设置决定),可以bind多个后级模块。
  2. Realtime mode

    • 只支持port 0/3。

    • 当port 0做Realtime mode时,只支持bind JPEG(hardward限制,帧率最高只有sensor的一半);建议port 0出YUV422(E_MI_SYS_PIXEL_FRAME_YUV422_YUYV),此时不占DRAM内存,而是占用SRAM。独占JPEG(不能再创建其他JPEG)。

    • 当Port 3做Realtime mode时,只支持bind divp,并且port 3独占DVIP(不能再创建其他DIVP)。

  3. ring mode

    • 只支持port 1。

    • 当Port 1做ring mode时,只支持 bind H264/H265。

    • 只占用半张或者一张yuv的内存。

    • Bind 之前需要调用MI_VENC_SetInputSourceConfig()将VENC设置成E_MI_VENC_INPUT_MODE_RING_HALF_FRM or E_MI_VENC_INPUT_MODE_RING_ONE_FRM

6.3. 模块之间的buffer传递

每个模块:

  • Input portbuffer是上一级输出的OutputPortBuf。

  • 模块之前buffer的传递是通过sys模块实现。

6.4. Frame mode的depth的概念

MI_S32 MI_SYS_SetChnOutputPortDepth(MI_SYS_ChnPort_t *pstChnPort , MI_U32 u32UserFrameDepth , MI_U32 u32BufQueueDepth);

说明:

  • ufQueueDepth:port能同时申请的最多buffer块数,默认为4;

  • UserFrameDepth: 能通过MI_SYS_ChnOutputPortGetBuf()同时取到不释放的最多buffer块数;

  • BufQueueDepth >= UserFrameDepth;

特点:

  • 不会同时申请depth张YUV,只会在使用的时候申请,使用完立即释放。

  • depth太少,CPU紧张的时候可能轮循不过来,导致丢帧。


6.5. Venc的output行为

以output buffer size(u32BufSize)为1M,u32MaxStrmCnt=4为例:Create venc的时候,output buffer(venc-ring-mem)即从mma里被申请好并且整块被映射成连续的虚拟地址。

  1. Encoder从output buffer的起始位置填编码帧,假设放完第4帧,output buffer尾部还剩余空间,encoder也不会接着第5帧,而会从起始位置放第5帧。

  2. 假设放完第1or2or3帧,output buffer尾部剩余的size < output buffer size / MaxStrmCnt即250K的时候,encoder也不会在尾部接着放,而会从起始位置放。

  3. 假设放完第1or2or3帧,output buffer尾部剩余size大于250K(假设是300K),但是接下来encoder编出了一帧大于300K的帧,那就会出现pack=2的情况,即将这一帧300K放在尾部,剩余放不下的继续从起始位置放。

问题举例:主码流4Mbps(20fps),分辨率却只有4CIF。经常出现buffer full打印。

原因:帧size太大,output buffer甚至放不下4张。 如果一直没有取流或者取流慢导致第1帧还没有被取走,则encoder会停止编码,直到空间被腾出来。

6.6. Sys模块负责的帧率控制

MI_S32 MI_SYS_BindChnPort2(MI_SYS_ChnPort_t *pstSrcChnPort, MI_SYS_ChnPort_t *pstDstChnPort,MI_U32 u32SrcFrmrate,    MI_U32 u32DstFrmrate, MI_SYS_BindType_e eBindType, MI_U32 u32BindParam);

SrcFrmrate:前一级实际进来帧率

DstFrmrate:输出给下一级的帧率

注:一个port后面bind多个模块时,建议所有后级模块的SrcFrmrate要相同。


6.7. SYS取流接口

取YUV数据(对应port的u32UserFrameDepth 需要大于0)

API (user mode)

  • MI_SYS_ChnOutputPortGetBuf

    从指定output端口获取Buffer(不会申请内存)

  • MI_SYS_ChnOutputPortPutBuf

    返还从指定output端口获取的buffer(不一定释放内存)

  • MI_SYS_GetFd

  • MI_SYS_CloseFd


6.8. RGN接口(OSD)

两种RGN:

  • OSD_TYPE(占内存)

  • COVER_TYPE(用作隐私遮挡,不占内存)

特点:

  1. 支持格式:I2/I4/I8/RGB565/ARGB1555/ARGB4444/ARGB8888

  2. 一个divp/vpe port可以attach多个 rgn,一个rgn可以attach到多个divp/vpe port。

  3. 所有通道的RGN必须是同一个format,不能一个RGN是bitmap1555,一个RGN是I4。

  4. 有些port不支持RGN。

OSD_TYPE两种画图方式:

  • MI_RGN_GetCanvasInfo();和MI_RGN_UpdateCanvas();

  • MI_RGN_SetBitMap();

COVER_TYPE RGN在attach时是相对位置,而不是绝对位置。

Sample code:
stChnPortParam.stPoint.u32X = x / 8192;
stChnPortParam.stPoint.u32Y = y / 8192;
stChnPortParam.unPara.stCoverChnPort.stSize.u32Width  = width / 8192;
stChnPortParam.unPara.stCoverChnPort.stSize.u32Height = height / 8192;

6.9. RGN的内存占用

COVER_TYPE RGN不占用内存。

OSD_TYPE RGN占用两种buffer:front buffer和back buffer。

注意:

rgn的handle假设有handle0和handle1都贴到同一个通道上(并且这个port已经超过4个RGN),分别两个线程:

  • handle0

    T0_0 = getcanvas

    T0_1 = update

  • handle1

    T1_0 = getcanvas

    T1_1 = update

有问题的执行顺序:

T0_0 -> T1_0 -> T0_1 -> T1_1

加mutex后:

lock-> T0_0 -> T0_1 -> unlock ->  lock -> T1_0  -> T1_1 -> unlock

6.10. RGN debug

  • 命令

    echo dumpRgnBuf [Handle] [Path] > /proc/mi_modules/mi_rgn/mi_rgn0
    
  • 功能

    Dump指定Region的buffer

  • 参数说明

    [Handle] region句柄

    [Path] 保存dump数据的路径。保存内容为region的canvas内容

  • 命令

    echo dumpFrontBuf [ModId] [ChnID] [PortID] [Path] > /proc/mi_modules/mi_rgn/mi_rgn0
    
  • 功能

    Dump指定channel和port的frontbuffer

  • 参数说明

    [ModId] 端口类型,Vpe为0,Divp为1。

    [ChnID] 通道号 [0 ~ 63]

    [PortID] 端口号 [0~3] [Path] 保存dump数据的路径。会根据当前实际使用的frontbuffer数量生成若干个文件


6.11. VENC接口

  • 编码特性和码率策略

    改变编码通道的参数:

    MI_VENC_CreateChn传入基础的chn参数

    MI_VENC_SetChnAttr传入可动态修改的chn参数

    MI_VENC_SetRcParam传入高级的RC参数

  • LTR机制

    避免因为GOP设太长而导致画面呼吸效应

    MI_VENC_SetRefParam()

    1. normal关系

      (GOP=20)

    2. 含长参考关系

      MI_VENC_SetRefParam:设置帧参考关系

      (base=1;enhance=4; EnablePred=1;GOP=20)

      (base=1;enhance=4; EnablePred=0;GOP=20)


7. 编码特性和码率策略

超大帧丢帧机制:控制I帧和P帧的大小,超出设定大小会重编或者丢帧。

MI_VENC_SetSuperFrameCfg:

设置超大帧模式和超大帧阀值(bit),有 DISCARD,Reencoder两种模式,335\337目前因为内存不充足,只支持DISCARD。

MI_VENC_SetRcPriority:

设置码率控制中目标码率和超大帧的优先级;当码率控制以目标码率为高优先级时,在码率不足时可能编码出超大帧以补偿码率,这时超大帧不会重编。当码率控制以超大帧阈值为高优先级时,超大帧则会重编以降低比特数,结果可能导致码率不足。

MI_VENC_SetIntraRefresh:

设置GDR(Gradual encoder refresh)功能。一般情况下I帧都会比P帧大几倍,如果在网络带宽有限的情况下,在传输I帧会造成一定的延迟,可能会有卡顿感,因此GDR将I帧取消掉,将一帧的intra区域按指定的行数(u32RefreshLineNum)平均分配到后续的P帧中,效果如下图:

优点:

  1. 码率非常平稳,对网络冲击小,适合无线传输环境。

  2. 编码,解码及网络延迟非常小

  3. 不会降低I帧质量,不会引起严重呼吸效应

缺点:

  1. 只支持normalP的GOP结构,其他GOP结构不支持

  2. 该技术主要针对码率平稳要求高的场景,并不能够降低太多码率

控制画面信息:

ROI功能:用户自定义某些区域的QP值,达到控制某些区域清晰度的目的

MI_VENC_SetRoiCfg:设置矩形的ROI区域。用户可以设置某个矩形区域的QP值,可以设置至多8个区域,区域的覆盖优先级由index决定

注意:335、337只支持相对的QP,即在当前QP的基础上加上一个偏移量

MI_VENC_SetRoiBgFrameRate:设置非ROI区域的帧率控制比例,根据用户设置的比例,一个GOP里面一些帧的非ROI区域会直接用上一帧对应区域的数据,从而降低数据量(非静止画面容量有画面割裂感)


8. Audio接口和VQE算法

8.1. 硬件流程

  1. 只支持16bit位宽

  2. Vqe 算法均支持 8/16K 采样率, 仅 ANR/AGC/EQ 支持 48K

8.2. 名词解释

SRC(Sample Rate Conversion),即resample,重采样,只支持8/16/32/48K互转。

AGC(Automatic Gain Control),自动增益控制,用于控制输出增益。

EQ(Equalizer),均衡器处理,用于对特定频段进行处理。

ANR(Acoustic Noise Reduction),降噪,用于去除环境中持续存在,频率固定的噪声。

BF(beamforming),波束成形算法,用于麦克风阵列,对声音进行增强。

AEC(Acoustic Echo Cancellation),回声消除。

SSL(Sound Source Localization),声源定位,用于麦克风阵列,识别声音的方向。

HPF(High-Pass Filtering),高通滤波

AED(Acoustic Event Detection),声音事件监测,目前仅能对婴儿哭声以及分贝过大的声音进行检测。

8.3. SW loop back和HW loop back的区别

HW loop back采用的参考数据从外部功放得来,而SW loop back从芯片内得来。参考sample code audio_all_test_case.c对接口的调用、MI_AI_SetExtAecChn。

8.4. Amic采样音频音量太小

AMIC在芯片内部会做两级AGAIN:

  • 模拟Gain:MI_AI_SetVqeVolume。

  • 数字Gain:MI_AI_SetChnParam里的u16RearGain是数字GAIN,u16FrontGain和模拟gain则是同一个值。

AGC算法:在AEC之后也可以起到拉高ai音量的作用。

建议先使用模拟gain,数字gain会同时放大电源噪声。

8.5. MI_AI_GetFrame每次取流长度不一的原因

VQE算法都是按128采样点处理,所以有开算法就需要把u32PtNumPerFrm(采样点每帧)设置成128的倍数,不然会取帧长度有时长有时短。


9. 内存使用说明、私有池、内存泄露排查手段

9.1. Mem分配

  • 内存管理

    1. mmap.ini 指定的,给HW预留的内存。

    2. mma,由cmd line传入kernel,来从mem中预留对应的config size,这部分mem主要提供给MI modules使用。

    3. cma,这部分在kernel config里指定,保留给emac,cipher和bdma使用。

    4. Linux manager Part

  • 内存分配 以335为例(64M DDR)

    查看

    bootargs=console=ttyS0,115200 root=/dev/mtdblock2 rootfstype=squashfs ro init=/linuxrc LX_MEM=0x3fe0000 mma_heap=mma_heap_name0,miu=0,sz=0x2000000 mma_memblock_remove=1
    

    可以用命令:

    cat /proc/mi_modules/mi_sys_mma/mma_heap_name0
    

    查看

    /kernel/arch/arm/config/infinity6b0_ssc009a_s01a_defconfig
    

    CONFIG_CMA_SIZE_MBYTES=2,表示预留2M cma,用于emac/cipher/bdma/sd卡等模块,可以用命令:

    cat /sys/class/mstar/msys/dmem
    

    查看 MMAP.ini (预留给硬件模块EMI)

    Free或者cat /proc/meminfo查看linux管理部分内存

    查看mma信息

    cat /proc/mi_modules/mi_sys_mma/mma_heap_name0
    

    查看cma信息

    cat /sys/class/mstar/msys/dmem
    

    查看Hardware保留部分

    Vi /config/mmap.ini
    

    因此文件系统里一定要放置config_tool和mmap.ini,可以在insmod sys.ko的时候用default_config_path=/program/lib/configs路径

    查看linux管理部分内存

    cat /proc/meminfo
    

    64M – 32M – 2M – 0x2000 – 28556Kb=1932kb是kernel image代码段和数据段, fdt,fdt指定的reserved-memory, 一级页表等。

9.2. Mma设置私有池

详见Private pool说明


10. HC HD FD算法说明

HC人形侦测算法(libHC_XS_ARM.a):只判断图像是否为人形(返回人形分数,分数越高越可能是人形)

HD人形检测算法(libfaster_HD_ARM.a):识别图像中有几个人形,分别给出每个人形的位置坐标

FD人脸检测算法(libFD_ARM.a):识别图像中有几个人脸,分别给出每个人脸的位置坐标

即想要HC又想要FD(libFD_HC_XS_ARM.a):注意只是两包模型包成一个库而已,用change_model()切换当前使用的模型。

接口说明:

详细请参考HD介绍及移植调试参考